package com.tg.app.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import com.tg.app.R;
import com.tange.module.device.feature.DeviceFeature;
import com.tg.app.listener.OnCameraZoomListener;
import com.tg.appcommon.android.TGLog;
import com.widget.OnRangeChangedListener;
import com.widget.RangeSeekBar;
import com.widget.VerticalRangeSeekBar;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Describe:
 * Created by Rance Rang on 2019-11-12.
 * <p>
 * Copyright (c) Tange.Inc All rights reserved.
 */
public class ZoomView extends LinearLayout  {
    public final static String TAG = "ZoomView";
    public final static int CAMERA_ZOOM_TYPE_UNKOWN = 0;//变焦倍数不可知
    public final static int CAMERA_ZOOM_TYPE_DEFINE = 1;//确定变焦数据的
    public final static int TCIC_LENS_ZOOM_IN = 23;
    public final static int TCIC_LENS_ZOOM_OUT = 24;
    public final static int TCIC_PTZ_STOP = 0;

    private VerticalRangeSeekBar seekBar;
    private boolean isSendLong = false;
    private final ZoomHelper mZoomHelper = new ZoomHelper();

    public boolean isFar(float zoomFactor){
        return mZoomHelper.isFar(zoomFactor);
    }

    private OnCameraZoomListener onCameraZoomListener;
    private LinearLayout mLinearLayout;
    public void setOnCameraZoomListener(OnCameraZoomListener onCameraZoomListener) {
        this.onCameraZoomListener = onCameraZoomListener;
    }

    private void showZoomInOut() {
        mLinearLayout.setVisibility(VISIBLE);
        seekBar.setVisibility(GONE);
    }

    public void parseZoomParam(DeviceFeature.ZoomFeature zoomFeature){
        mZoomHelper.parseParam(zoomFeature);
    }

    public void initZoom(DeviceFeature.ZoomFeature zoomFeature) {
        seekBar.setVisibility(GONE);

        if (zoomFeature ==null) {
            return;
        }
        mZoomHelper.parseParam(zoomFeature);
        if (zoomFeature.maxFactor>1){
            seekBar.setSteps(mZoomHelper.getStep());
            if (mZoomHelper.getStep() != 0){
                seekBar.setRange(1.0f, Math.max(mZoomHelper.getMaxFactor(), 1.0f));
            }
            seekBar.setVisibility(VISIBLE);
            mLinearLayout.setVisibility(GONE);
        }else{
            showZoomInOut();
        }
    }

    public float modifyZoomFactor(float progress){
        float nStep = (mZoomHelper.getMaxFactor()-1)/mZoomHelper.getStep();
        try {
            BigDecimal b = new BigDecimal((progress-1.0f)/nStep);
            float tmp = b.setScale(0, RoundingMode.HALF_UP).floatValue();
            TGLog.d(TAG,"progress = " + progress + ",nStep = " + nStep + ", tmp = " + tmp);
            BigDecimal bb = new BigDecimal(1.0f + nStep *  tmp);
            return bb.setScale(1, RoundingMode.HALF_UP).floatValue();
        }catch (Exception ignored){

        }
        return 1.0f;
    }

    public void setZoomFactor(float zoomFactor) {
        mZoomHelper.setZoomFactor(zoomFactor);
        if (seekBar.getVisibility() == VISIBLE) {
            float progress = zoomFactor * (mZoomHelper.getMaxFactor()-1) + 1.0f;
            if (progress<0){
                progress = 1;
            }
            progress = modifyZoomFactor(progress);
            TGLog.d(TAG,"zoomFactor = " + zoomFactor + ",zoomFactor = " + mZoomHelper.getMaxFactor() + ", zoomview Visible = " + getVisibility() + ", progress =" + progress + ", channel =" + mZoomHelper.getIndex());
            seekBar.setProgress(progress);
        }
    }

    public ZoomView(Context context) {
        super(context);
        initView(context);
    }

    public ZoomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public ZoomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }


    private void initView(Context context) {
        @SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.layout_zoom, null);
        seekBar = view.findViewById(R.id.seekbar_zoom);
        addView(view);
        View zoomIn = view.findViewById(R.id.iv_zoom_in);
        View zoomOut = view.findViewById(R.id.iv_zoom_out);
        mLinearLayout = view.findViewById(R.id.ll_1);

        seekBar.setOnRangeChangedListener(new OnRangeChangedListener() {
            @Override
            public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
                TGLog.d("isFromUser:" + isFromUser +  ",leftValue = " + leftValue + ", right = " + rightValue + ", seekbar-left = " + view.getLeftSeekBar().getProgress());
                if (isFromUser && onCameraZoomListener != null){
                    leftValue = modifyZoomFactor(leftValue);
                    TGLog.d("onRangeChanged = " + leftValue);
                    onCameraZoomListener.onZoomChanging(leftValue, mZoomHelper.getIndex());
                }
            }

            @Override
            public float onModifyProgress(float progress) {
                progress = modifyZoomFactor(progress);
                TGLog.d("onModifyProgress = " + progress);
                return progress;
            }

            @Override
            public void onStartTrackingTouch(RangeSeekBar view, boolean isLeft) {

            }

            @Override
            public void onStopTrackingTouch(RangeSeekBar view, boolean isLeft) {
                TGLog.d("isLeft = "+isLeft);
                if (isLeft){
                    TGLog.d("val = " + view.getLeftSeekBar().getProgress());
                }
                updateZoom(true);
            }
        });
        View.OnTouchListener listener = (v, event) -> {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:{
                    onClick(v);
                }
                case MotionEvent.ACTION_UP: {
                    if (isSendLong){
                        sendUnkown(TCIC_PTZ_STOP);
                        isSendLong = false;
                    }
                }
            }
            return false;
        };
        zoomIn.setOnTouchListener(listener);
        zoomOut.setOnTouchListener(listener);
        zoomIn.setOnLongClickListener(v -> {
            sendUnkown(TCIC_LENS_ZOOM_IN);
            isSendLong = true;
            return false;
        });
        zoomOut.setOnLongClickListener(v -> {
            sendUnkown(TCIC_LENS_ZOOM_OUT);
            isSendLong = true;
            return false;
        });

    }

    public void setSeekBarEnabled(boolean enabled) {
        seekBar.setEnabled(enabled);
    }

    private void updateZoom(boolean isSeekbar) {
        float progress = seekBar.getLeftSeekBar().getProgress();
        TGLog.d(TAG,"updateZoom =  borderFactor " + mZoomHelper.getBorderFactor() + ", zoomFactor = " + mZoomHelper.getZoomFactor() + ", progress = " + progress + ", isSeekbar = " + isSeekbar);
        if (onCameraZoomListener != null) {
            BigDecimal b = new BigDecimal((progress - 1.0f)/(mZoomHelper.getMaxFactor() - 1.0f));
            float tmp = b.setScale(6,  BigDecimal.ROUND_HALF_DOWN).floatValue();
            mZoomHelper.setZoomFactor(tmp);
            onCameraZoomListener.onZoom(CAMERA_ZOOM_TYPE_DEFINE, mZoomHelper.getZoomFactor(), isSeekbar, mZoomHelper.getIndex());
            onCameraZoomListener.onZoomChangeState(mZoomHelper.getBorderFactor(), progress, mZoomHelper.getIndex());
        }
    }
    private void sendUnkown(int scale){
        if (onCameraZoomListener!=null){
            onCameraZoomListener.onZoom(CAMERA_ZOOM_TYPE_UNKOWN, scale,false, mZoomHelper.getIndex());
        }
    }


    private void onClick(View v) {
        int id = v.getId();
        if (id == R.id.iv_zoom_in) {
            if (seekBar.getVisibility() == VISIBLE) {
                int p = (int)seekBar.getLeftSeekBar().getProgress() + 1;
                if (p <= seekBar.getMaxProgress()) {
                    seekBar.setProgress(p);
                    updateZoom(false);
                }
            } else {
                sendUnkown(1);
            }
        } else if (id == R.id.iv_zoom_out) {
            if (seekBar.getVisibility() == VISIBLE) {
                int p = (int)seekBar.getLeftSeekBar().getProgress() - 1;
                if (p >= 0) {
                    seekBar.setProgress(p);
                    updateZoom(false);
                }
            } else {
                sendUnkown(-1);
            }
        }
    }
}
